﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Security.Principal;
using System.Web.Mvc;
using System.Web.Routing;
using good1.ApplicationServices.Interface;
using good1.Web.Controllers.Attributes;
using good1.Web.Controllers.Extensions;
using good1.Web.Controllers.Infrastructure;
using good1.Web.Model;
using SharpArch.Core;

namespace good1.Web.Controllers
{
    [HandleErrorAttributeCustom]
    public class BaseController :  Controller
    {
        private readonly ISecurityContextService securityContext;
        public ISecurityContextService SecurityContext { get { return securityContext; } }
        
        public BaseController(ISecurityContextService securityContext)
        {
            Check.Require(securityContext != null, "goodCookies may not be null");
            this.securityContext = securityContext;

            SecurityCheck();            
        }

        private void SecurityCheck()
        {
            if (securityContext == null) return;
            GenericPrincipal user = securityContext.GetPrincipal();
            if (user == null) return;
            HttpContextFactory.GetHttpContext().User = user;
        }

        public T CreateViewData<T>() where T : BaseViewData, new()
        {
            T viewData = new T
            {
                FriendlyName = securityContext.FriendlyName
                //TODO could add things like client ip here
            };
            
            return viewData;
        }

        /// <summary>
        /// Useful if say view was created by Mapping and want to set this data afterwards, i.e. not wanting a new instance just an updated one
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public T SetViewData<T>(T t) where T : BaseViewData, new()
        {
            t.FriendlyName = securityContext.FriendlyName;
            return t;
        }


        public RedirectToRouteResult RedirectToAction<TController>(Expression<Func<TController, object>> actionExpression)
        {
            string controllerName = typeof(TController).GetControllerName();
            string actionName = actionExpression.GetActionName();

            return RedirectToAction(actionName, controllerName);
        }

        public RedirectToRouteResult RedirectToAction<TController>(Expression<Func<TController, object>> actionExpression,
                                                                   IDictionary<string, object> dictionary)
        {
            string controllerName = typeof(TController).GetControllerName();
            string actionName = actionExpression.GetActionName();

            return RedirectToAction(actionName, controllerName,
                                    new RouteValueDictionary(dictionary));
        }

        public RedirectToRouteResult RedirectToAction<TController>(Expression<Func<TController, object>> actionExpression,
                                                                   object values)
        {
            string controllerName = typeof(TController).GetControllerName();
            string actionName = actionExpression.GetActionName();

            return RedirectToAction(actionName, controllerName,
                                    new RouteValueDictionary(values));
        }
    
    }
}
